<?php
namespace Yousheng\Ku;
use Illuminate\Support\Str;

/**
 * It is used by parent class of various resolver classes.
 */
final class Column /* implements \Stringable */{
    public function __construct(
        public string $field,
        public string $type,
        public bool $unsigned = false,
        public bool $autoIncrement = false,
        public bool $notNull = false,
        public bool $primaryKey = false,
        public ?string $bracket = null,
        public ?string $default = null,
        public ?string $extra = null,
        public string $tableName = '',
    ) {
        $this->type = strtolower($type);
    }
    public function toArray(): array
    {
        return [
            'field' => $this->field,
            'type' => $this->type,
            'unsigned' => $this->unsigned,
            'notNull' => $this->notNull,
            'autoIncrement' => $this->autoIncrement,
            'bracket' => $this->bracket,
            'primaryKey' => $this->primaryKey,
            'default' => $this->default,
            'extra' => $this->extra,
            'tableName' => $this->tableName,
        ];
    }

    /**
     * Create a instance.
     *
     * @param  string  $field  Name of the column
     * @param  string  $type  Type of the column
     * @param  bool  $unsigned  Nullable flag
     * @param  bool  $autoIncrement  Nullable flag
     * @param  bool  $notNull  Nullable flag
     * @param  bool  $primaryKey  Key of the column
     * @param  string|null  $bracket  Length or something of the column
     * @param  string|null  $default  Default value
     * @param  string|null  $extra  Extra information of the column
     */
    public static function make(
        string $field,
        string $type,
        bool $unsigned = false,
        bool $autoIncrement = false,
        bool $notNull = false,
        bool $primaryKey = false,
        ?string $bracket = null,
        ?string $default = null,
        ?string $extra = null,
        ?string $tableName = '',
    ): static {
        return new self(
            $field,
            $type,
            $unsigned,
            $autoIncrement,
            $notNull,
            $primaryKey,
            $bracket,
            $default,
            $extra,
            $tableName
        );
    }

    /**
     * Get the row string form database factory, then return the string for Seeder class.
     *
     * @return string The method returns a Seeder class row string
     */
    public function fake(): string
    {
        return ResolverSelector::of($this)->fake();
    }

    /**
     * Get the row string for migration file, then return the string for migration class.
     *
     * @return string The method returns a Migration class row string
     */
    public function migration(): string
    {
        return ResolverSelector::of($this)->migration();
    }

    /**
     * Get the row string for migration file, then return the string for migration class.
     *
     * @return string The method returns a Migration class row string
     */
    public function novaField(): string
    {
        return ResolverSelector::of($this)->nova();
    }

    /**
     * Get the title for Nova field title from column name.
     *
     * @return string The method returns the title for Nova field title
     *
     * @example echo (new Column(['username', 'varchar']))->title();
     * //=> Username
     */
    public function title(): string
    {
        return Str::title($this->field);
    }

    /**
     * Class magic method to get the instance information for a Exception
     *
     * @return string The method returns the instance information for a Exception
     */
    // public function __toString(): string
    // {
    //     return 'Field is '.$this->field.' and type is '.$this->type.'.';
    // }

    public function cast(): ?string
    {
        return ResolverSelector::of($this)->cast();
    }

/* 
# 1.数值类型
整数类型：用于存储整数，包含 TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT，这些类型在存储范围和占用空间上存在差异。例如，TINYINT 一般占用 1 字节，范围是 -128 到 127（有符号）或者 0 到 255（无符号）；而 BIGINT 占用 8 字节，范围更大。
浮点类型：用于存储带有小数部分的数字，包括 FLOAT 和 DOUBLE。FLOAT 是单精度浮点数，通常占用 4 字节；DOUBLE 是双精度浮点数，一般占用 8 字节。
定点类型：DECIMAL 类型用于精确的小数计算，在存储精确的数值，如货币金额时很有用。

# 2.日期和时间类型
DATE：用于存储日期，格式为 YYYY-MM-DD。
TIME：用于存储时间，格式为 HH:MM:SS。
DATETIME：用于存储日期和时间，格式为 YYYY-MM-DD HH:MM:SS。
TIMESTAMP：同样用于存储日期和时间，不过范围比 DATETIME 小，并且会受时区影响。
YEAR：用于存储年份，可以是 2 位或 4 位格式。

# 3.字符串类型
CHAR：固定长度的字符串，最多能存储 255 个字符。当存储的数据长度小于定义的长度时，会用空格填充。
VARCHAR：可变长度的字符串，最多能存储 65,535 个字符。它只会占用实际存储数据所需的空间。
TEXT：用于存储大量文本数据，有 TINYTEXT、TEXT、MEDIUMTEXT 和 LONGTEXT 几种类型，存储容量逐渐增大。
ENUM：从预定义的字符串列表里选择一个值进行存储。
SET：从预定义的字符串列表里选择零个或多个值进行存储。

# 4.二进制类型
BINARY：固定长度的二进制字符串，最多能存储 255 个字节。
VARBINARY：可变长度的二进制字符串，最多能存储 65,535 个字节。
BLOB：用于存储大量二进制数据，有 TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB 几种类型，存储容量逐渐增大。

# 5.JSON 类型
JSON：用于存储 JSON 格式的数据，方便对 JSON 数据进行操作和查询。

# 6.空间类型
GEOMETRY：可存储任何类型的几何对象。
POINT：用于存储点的坐标。
LINESTRING：用于存储线的信息。
POLYGON：用于存储多边形的信息。 */
 
}